package sensorBoard.sensor;

import sensorBoard.ISensorBoardComponent;
import sensorBoard.ISensorBoardComponentListener;

import com.CharNotValidException;
import com.Event;
import com.LedsManager;
import com.ParamNotFoundException;
import com.ParamsLabel;
import com.sun.spot.sensorboard.EDemoBoard;
import com.sun.spot.sensorboard.peripheral.ITemperatureInput;
import com.sun.spot.sensorboard.peripheral.ITemperatureInputThresholdListener;
import com.sun.spot.resources.transducers.LEDColor;

/**
 * Provides a listener class for Temperature Sensor. 
 * Send a backEvent to own manager when the temperature value changes from the threshold value
 * @author Francesco Aiello, Antonio Guerrieri, Raffaele Gravina
 *
 */
public class TemperatureListener implements ITemperatureInputThresholdListener, ISensorBoardComponentListener {
	
	private ISensorBoardComponent sensorBoardComponent;
	private String sensorID;
	private	Event backEvent;
	private double lowValue;
	private double highValue;
	private ITemperatureInput temperatureSensor;
	boolean permanent;
	
	/**
	 * Creates a new TemperatureListener
	 * @param sensorBoardComponent component that invokes the constructor and manages the event transmission
	 * @param sensorID own ID
	 * @param backEvent to send when the temperature values changes from the threshold values
	 */
	public TemperatureListener (ISensorBoardComponent sensorBoardComponent, String sensorID, Event backEvent) {
		
		try {
			this.sensorBoardComponent = sensorBoardComponent;
			this.sensorID = sensorID;
			this.backEvent = backEvent;
			this.backEvent.setParam(ParamsLabel.SNS_ID, sensorID);
			if (backEvent.getType() == Event.PERMANENT)
				this.permanent = true;
			else
				this.permanent = false;
			this.temperatureSensor = EDemoBoard.getInstance().getADCTemperature();
			this.temperatureSensor.addITemperatureInputThresholdListener(this);
			this.temperatureSensor.enableThresholdEvents(true);
			this.lowValue = Double.parseDouble(backEvent.getParam(ParamsLabel.TMP_THRESHOLD_LOW_VALUE));
			this.highValue = Double.parseDouble(backEvent.getParam(ParamsLabel.TMP_THRESHOLD_HIGH_VALUE));
			this.temperatureSensor.setThresholds(this.lowValue, this.highValue, true);
			this.temperatureSensor.enableThresholdEvents(true);
		}
		catch (NumberFormatException e) {
			LedsManager.error(LEDColor.YELLOW);
			e.printStackTrace();
		}
		catch (ParamNotFoundException e) {
			LedsManager.error(LEDColor.YELLOW);
			e.printStackTrace();
		}
		catch (CharNotValidException e) {
			LedsManager.error(LEDColor.YELLOW);
			e.printStackTrace();
		}
		
	}

	public void thresholdChanged(ITemperatureInput temperatureSensor, double low, double high,  boolean inCelsius) {
		try {
			backEvent.setParam(ParamsLabel.TMP_THRESHOLD_LOW_VALUE, "" + low);
			backEvent.setParam(ParamsLabel.TMP_THRESHOLD_HIGH_VALUE, "" + high);
			this.sensorBoardComponent.send(backEvent);
			this.temperatureSensor.enableThresholdEvents(true);
		}
		catch (CharNotValidException e) {
			LedsManager.error(LEDColor.YELLOW);
			e.printStackTrace();
		}
	}
	
	public void thresholdExceeded(ITemperatureInput temperatureSensor, double value, boolean inCelsius) {
		try {
			if (value <=  this.lowValue || value >= this.highValue) {
				backEvent.setParam(ParamsLabel.TMP_TEMPERATURE_VALUE, "" + value);
				this.sensorBoardComponent.send(backEvent);
				if (this.permanent)
					this.temperatureSensor.enableThresholdEvents(true);
				else 
					this.sensorBoardComponent.terminateListener(this.sensorID);
			}
		}
		catch (CharNotValidException e) {
			LedsManager.error(LEDColor.YELLOW);
			e.printStackTrace();
		}		
	}
	
	public boolean terminateListener () {
		this.temperatureSensor.removeITemperatureInputThresholdListener(this);
		return true;
	}

	public String getSensorBoardComponentID() {
		return sensorID;
	}
	
}
